const { RandomForestClassifier } = require('ml-random-forest')
const path = require('path')
const ROOT_DIR = path.join(__dirname, '..')
const HELPERS_DIR = path.join(ROOT_DIR, 'helpers')
const { readAllValues } = require(path.join(HELPERS_DIR, 'readAllValues.js'))
const historicalData = readAllValues('m') // 读取数据

// 加权频率统计
const weightedFrequencyMap = {}
const weightFactor = 1.2 // 权重因子，越大，越倾向于最近的数据

// 根据历史数据计算加权频率
historicalData.forEach((record, index) => {
  const number = record.number
  const weight = Math.pow(weightFactor, historicalData.length - index - 1) // 越靠近最近的数据权重越大

  if (weightedFrequencyMap[number]) {
    weightedFrequencyMap[number] += weight
  } else {
    weightedFrequencyMap[number] = weight
  }
})

// 排序号码，出现频率加权后从高到低
const weightedSortedNumbers = Object.entries(weightedFrequencyMap).sort((a, b) => b[1] - a[1])

// 获取出现频率最高的前24个号码
const weightedTop24Numbers = weightedSortedNumbers.slice(0, 24).map((entry) => entry[0])
console.log('加权频率排名前24的号码:', weightedTop24Numbers)

// 随机森林特征准备
const createFeatures = (historicalData, sequenceLength = 5) => {
  const X = []
  const y = []

  for (let i = 0; i < historicalData.length - sequenceLength; i++) {
    const features = []
    for (let j = 0; j < sequenceLength; j++) {
      features.push(parseInt(historicalData[i + j].number, 10))
    }
    X.push(features)
    y.push(parseInt(historicalData[i + sequenceLength].number, 10)) // 下一个号码作为标签
  }

  return { X, y }
}

// 创建特征和标签
const { X, y } = createFeatures(historicalData)

// 构建随机森林分类器
const classifier = new RandomForestClassifier({
  nEstimators: 100, // 设定森林的树木数量
  maxDepth: 10, // 设置树的最大深度
  minSamplesSplit: 2 // 设置分裂一个节点所需的最小样本数
})

// 训练随机森林模型
classifier.train(X, y)

// 使用随机森林模型进行预测
const predictNextNumberWithRandomForest = (sequence) => {
  const prediction = classifier.predict([sequence])
  return prediction[0]
}

// 获取24个预测号码
const predict24Numbers = (initialSequence, numPredictions = 24) => {
  let sequence = [...initialSequence]
  const predictions = []

  for (let i = 0; i < numPredictions; i++) {
    // 每次预测时使用不同的输入序列
    const prediction = predictNextNumberWithRandomForest(sequence)
    predictions.push(prediction)

    // 更新输入序列，去掉第一个元素，加入新的预测号码
    sequence = sequence.slice(1).concat(prediction)

    // 引入微小的随机扰动，确保不同的预测
    // 可以选择加入一些扰动（例如加入 +1 或 -1），但不要超过预测的最大范围
    if (Math.random() < 0.1) {
      // 10%的概率进行扰动
      const perturbation = Math.floor(Math.random() * 2) === 0 ? 1 : -1 // 随机扰动 +1 或 -1
      sequence[sequence.length - 1] = Math.max(1, Math.min(49, sequence[sequence.length - 1] + perturbation)) // 限制在1到49之间
    }
  }

  return predictions
}

// 假设我们选择最后5期号码作为初始输入进行预测
const lastSequence = historicalData.slice(-5).map((record) => parseInt(record.number, 10))

// 预测24个号码
const predictedNumbers = predict24Numbers(lastSequence)
console.log('预测的24个号码:', predictedNumbers)
